import { IUser } from '@database/models/User';
import Role from '@database/models/Role';
import Permission from '@database/models/Permission';
import Organization from '@database/models/Organization';
import Team from '@database/models/Team';
import mongoose from 'mongoose';

/**
 * 权限检查工具类
 */
export class PermissionChecker {
  /**
   * 检查用户是否有全局权限（系统级）
   */
  static async hasGlobalPermission(user: IUser, permissionName: string): Promise<boolean> {
    if (!user.globalRoles || user.globalRoles.length === 0) {
      return false;
    }

    const roles = await Role.find({ _id: { $in: user.globalRoles } }).populate('permissions');
    const permission = await Permission.findOne({ name: permissionName });

    if (!permission) {
      return false;
    }

    for (const role of roles) {
      if (role.permissions.some((p: any) => p._id.toString() === permission._id.toString())) {
        return true;
      }
    }

    return false;
  }

  /**
   * 检查用户在组织中是否有权限
   */
  static async hasOrganizationPermission(
    user: IUser,
    organizationId: string,
    permissionName: string
  ): Promise<boolean> {
    // 检查全局权限（系统管理员）
    if (await this.hasGlobalPermission(user, permissionName)) {
      return true;
    }

    // 检查是否是组织成员
    if (!user.isMemberOfOrganization(organizationId)) {
      return false;
    }

    // 检查组织级权限
    return await user.hasPermissionInOrganization(organizationId, permissionName);
  }

  /**
   * 检查用户在团队中是否有权限
   */
  static async hasTeamPermission(
    user: IUser,
    teamId: string,
    permissionName: string
  ): Promise<boolean> {
    // 获取团队信息
    const team = await Team.findById(teamId);
    if (!team) {
      return false;
    }

    // 检查组织级权限
    if (await this.hasOrganizationPermission(user, team.organization.toString(), permissionName)) {
      return true;
    }

    // 检查是否是团队负责人
    if (team.isLeader(user._id.toString())) {
      // 团队负责人有团队内的所有权限
      return true;
    }

    // 检查团队权限
    const memberRole = team.getMemberRole(user._id.toString());
    if (!memberRole) {
      return false;
    }

    // 根据团队角色判断权限
    if (memberRole === 'viewer') {
      // 只读用户只能查看
      return permissionName.endsWith(':read');
    }

    return team.permissions.includes(permissionName);
  }

  /**
   * 检查用户是否是组织管理员
   */
  static async isOrganizationAdmin(user: IUser, organizationId: string): Promise<boolean> {
    const organization = await Organization.findById(organizationId);
    if (!organization) {
      return false;
    }

    return organization.isAdmin(user._id.toString());
  }

  /**
   * 检查用户是否是组织所有者
   */
  static async isOrganizationOwner(user: IUser, organizationId: string): Promise<boolean> {
    const organization = await Organization.findById(organizationId);
    if (!organization) {
      return false;
    }

    return organization.isOwner(user._id.toString());
  }

  /**
   * 检查用户是否是团队负责人
   */
  static async isTeamLeader(user: IUser, teamId: string): Promise<boolean> {
    const team = await Team.findById(teamId);
    if (!team) {
      return false;
    }

    return team.isLeader(user._id.toString());
  }

  /**
   * 获取用户的所有权限（去重）
   */
  static async getUserAllPermissions(
    user: IUser,
    organizationId?: string
  ): Promise<string[]> {
    const permissionNames = new Set<string>();

    // 全局角色权限
    if (user.globalRoles && user.globalRoles.length > 0) {
      const globalRoles = await Role.find({ _id: { $in: user.globalRoles } }).populate('permissions');
      for (const role of globalRoles) {
        for (const permission of role.permissions as any[]) {
          permissionNames.add(permission.name);
        }
      }
    }

    // 组织角色权限
    if (organizationId) {
      const roleIds = user.getRolesInOrganization(organizationId);
      if (roleIds.length > 0) {
        const orgRoles = await Role.find({ _id: { $in: roleIds } }).populate('permissions');
        for (const role of orgRoles) {
          for (const permission of role.permissions as any[]) {
            permissionNames.add(permission.name);
          }
        }
      }
    }

    return Array.from(permissionNames);
  }

  /**
   * 批量检查权限
   */
  static async hasAnyPermission(
    user: IUser,
    organizationId: string,
    permissionNames: string[]
  ): Promise<boolean> {
    for (const permissionName of permissionNames) {
      if (await this.hasOrganizationPermission(user, organizationId, permissionName)) {
        return true;
      }
    }
    return false;
  }

  /**
   * 检查是否拥有所有权限
   */
  static async hasAllPermissions(
    user: IUser,
    organizationId: string,
    permissionNames: string[]
  ): Promise<boolean> {
    for (const permissionName of permissionNames) {
      if (!(await this.hasOrganizationPermission(user, organizationId, permissionName))) {
        return false;
      }
    }
    return true;
  }
}

/**
 * 快捷权限检查函数
 */

// 检查资源读取权限
export const canRead = (resource: string) => async (user: IUser, orgId: string) => {
  return await PermissionChecker.hasOrganizationPermission(user, orgId, `${resource}:read`);
};

// 检查资源创建权限
export const canCreate = (resource: string) => async (user: IUser, orgId: string) => {
  return await PermissionChecker.hasOrganizationPermission(user, orgId, `${resource}:create`);
};

// 检查资源更新权限
export const canUpdate = (resource: string) => async (user: IUser, orgId: string) => {
  return await PermissionChecker.hasOrganizationPermission(user, orgId, `${resource}:update`);
};

// 检查资源删除权限
export const canDelete = (resource: string) => async (user: IUser, orgId: string) => {
  return await PermissionChecker.hasOrganizationPermission(user, orgId, `${resource}:delete`);
};

// 检查资源管理权限
export const canManage = (resource: string) => async (user: IUser, orgId: string) => {
  return await PermissionChecker.hasOrganizationPermission(user, orgId, `${resource}:manage`);
};

export default PermissionChecker;
